package com.example.spingsercurity2.util;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Clock;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.impl.DefaultClock;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

/**
 生成token工具类
 **/
@ConfigurationProperties(prefix = "jwt")
@Component
public class JwtTokenUtils {

	public static final String TOKEN_HEADER = "Authorization";

	public static final String TOKEN_PREFIX = "Bearer ";

	// 密钥，用于signature（签名）部分解密
	private static final String PRIMARY_KEY = "HHS_fast_java_plat";
	// 签发者
	private static final String ISS = "HanSan.HU";
	// 添加角色的key
	private static final String ROLE_CLAIMS = "role";

	// 过期时间是3600秒，既是1个小时
	private static final long EXPIRATION = 3600L;

	// 选择了记住我之后的过期时间为7天
	private static final long EXPIRATION_REMEMBER = 604800L;

	//..省略get set方法

	//jdk8新增的时钟类
	private Clock clock = DefaultClock.INSTANCE;

	/**
	 * 使用用户名作为身份信息生成Token
	 * @param identityId     用户身份标识
	 * @param identityId     用户的角色权限信息
	 */
	public Map getToken(String identityId, List<String> Authorizes) {
		Date nowDate = new Date();
		//token过期时间
		long expireAt=nowDate.getTime() + EXPIRATION * 1000;
		Date expireDate = new Date(expireAt);
		Map map=new HashMap<>();
		map.put("expireAt",expireAt);
		String token= Jwts.builder()
			//放入唯一标识,可以是用户名或者Id
			.setSubject(identityId)
			.setIssuedAt(nowDate)
			.setExpiration(expireDate)
			.signWith(SignatureAlgorithm.HS512, PRIMARY_KEY)
			//自定义属性 放入用户拥有角色和权限
			.claim("roleAuthorizes", Authorizes)
			.compact();
		map.put("token",token);
		return map;
	}

	/**
	 * 根据token获取身份信息
	 */
	public Claims getTokenClaim(String token) {
		try {
			return Jwts.parser().setSigningKey(PRIMARY_KEY).parseClaimsJws(token).getBody();
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	/**
	 * 判断token是否失效
	 */
	public boolean isTokenExpired(String token) {
		final Date expiration = getExpirationDateFromToken(token);
		return expiration.before(clock.now());
	}

	/**
	 * 根据token获取username
	 */
	public String getUsernameFromToken(String token) {
		return getClaimFromToken(token, Claims::getSubject);
	}

	/**
	 * 根据token获取失效时间
	 */
	public Date getExpirationDateFromToken(String token) {
		return getClaimFromToken(token, Claims::getExpiration);
	}

	public <T> T getClaimFromToken(String token, Function<Claims, T> claimsResolver) {
		final Claims claims = getTokenClaim(token);
		return claimsResolver.apply(claims);
	}

	//
    // //获得请求头
	//public String getTokenHead() {
	//	return TOKEN_HEADER;
	//}
}

